<template>
  <div class="page-login">
    <div class="header">
      <img
        src="https://image.xuexiwangzhe.com/FiBF-GsFNMDGJeX1MdtwSx7GsOPN"
        class="header-img"
      />
      <div>学习王者</div>
    </div>
    <div v-if="loginType == 'bindwx'">
      <div class="bindwx-title" v-if="!bindWxCodeSuccess">
        绑定个人微信，以便扫码登录
      </div>
      <div class="bindwx-title" v-else>
        <img
          class="bindwx-title-img"
          src="https://image.xuexiwangzhe.com/FsCgkduGFH-6obpiE6mN29MzBMQ4"
        />
        <div>绑定成功</div>
      </div>
      <img class="bindwx-img" :src="baseImgUrl + qrCode" />
      <div v-if="!bindWxCodeSuccess" class="bindwx-tip">
        打开微信扫一扫，绑定您的学习王者
      </div>
      <div v-else class="bindwx-tip">
        <span style="color:#3366FF;margin-right:3px;">{{
          loginTimeNumber
        }}</span
        >秒后自动跳转
      </div>
    </div>
    <div class="main" v-else>
      <div class="main-info">
        <div class="main-info-tip">
          督学促练<br />
          显著提升效率和效果
        </div>
        <img
          src="https://image.xuexiwangzhe.com/FrOZ3sHCAv8ija72J2ztFRzQCmzu"
          class="main-info-img"
        />
      </div>
      <div class="main-login-box" v-if="loginType == 'code'">
        <div class="main-login-select">
          <img
            src="https://image.xuexiwangzhe.com/FomGU14PV1A6AMLWEjX4mVyt79rH"
            class="main-login-select-img"
            @click="loginType = 'wx'"
          />
        </div>
        <div class="main-login-title">欢迎使用学习王者</div>
        <mu-form :model="codeForm">
          <mu-form-item
            class="main-login-input-form-item"
            label="请输入手机号"
            :label-float="true"
            prop="phone"
          >
            <mu-text-field v-model="codeForm.phone"></mu-text-field>
          </mu-form-item>
          <mu-form-item class="main-login-btn-form-item">
            <mu-button
              class="main-login-btn"
              v-if="!verifyInterval"
              :class="{ 'main-login-btn-disabled': !codeForm.phone }"
              :disabled="!codeForm.phone"
              @click="getVerifyCode(codeForm.phone)"
              >获取短信验证码</mu-button
            >
            <mu-button
              class="main-login-btn main-login-btn-disabled"
              v-else
              disabled
              >({{ verifyTime }}s)获取短信验证码</mu-button
            >
          </mu-form-item>
        </mu-form>
        <div class="main-login-tip">
          未注册的用户，手机验证后自动创建学习王者帐户
        </div>
        <div class="main-login-bottom">
          登录即代表同意学习王者的《<span class="main-login-bottom-name"
            >用户协议</span
          >》和《<span class="main-login-bottom-name">隐私政策</span>》
        </div>
      </div>
      <div class="main-login-box" v-else-if="loginType == 'wx'">
        <div class="main-login-select">
          <img
            src="https://image.xuexiwangzhe.com/Fkex_nOkTZ_sG87n32UGdL-vWY-9"
            class="main-login-select-img"
            @click="loginType = 'code'"
          />
        </div>
        <div class="main-login-title" style="margin-bottom:54px;">
          欢迎使用学习王者
        </div>

        <mu-circular-progress
          v-if="wxCodeLoading"
          class="demo-circular-progress wxcode-loading"
          :size="36"
        ></mu-circular-progress>
        <img class="main-login-qr-img" v-else :src="baseImgUrl + qrCode" />
        <div class="main-login-qr-tip">打开微信，扫一扫</div>
        <div class="main-login-tip">
          未注册的用户，微信扫码后自动创建学习王者帐户
        </div>
        <div class="main-login-bottom">
          登录即代表同意学习王者的《<span class="main-login-bottom-name"
            >用户协议</span
          >》和《<span class="main-login-bottom-name">隐私政策</span>》
        </div>
      </div>
      <div class="main-login-box" v-else-if="loginType == 'codecheck'">
        <div class="main-login-select" @click="loginType = 'wx'">
          <img
            src="https://image.xuexiwangzhe.com/FomGU14PV1A6AMLWEjX4mVyt79rH"
            class="main-login-select-img"
          />
        </div>
        <div class="main-login-back" @click="loginType = 'code'">
          <img
            src="https://image.xuexiwangzhe.com/Fgdkib5gzIWFGI3TmxjyqMhTtMNZ"
            class="main-login-back-img"
          />
        </div>
        <div class="main-login-title" style="margin-bottom:50px;">
          验证手机号
        </div>
        <div class="main-login-check-tip" style="margin-bottom:36px;">
          验证码已发送到你的手机：<span class="main-login-check-tip-phone">{{
            codeForm.phone
          }}</span>
        </div>
        <mu-form
          class="main-login-check-form"
          :inline="true"
          :model="codeCheckForm"
        >
          <mu-form-item class="main-login-input-check-form-item" prop="one">
            <mu-text-field
              id="input_one"
              v-model="codeCheckForm.one"
            ></mu-text-field>
          </mu-form-item>
          <mu-form-item class="main-login-input-check-form-item" prop="two">
            <mu-text-field
              id="input_two"
              v-model="codeCheckForm.two"
            ></mu-text-field>
          </mu-form-item>
          <mu-form-item class="main-login-input-check-form-item" prop="three">
            <mu-text-field
              id="input_three"
              v-model="codeCheckForm.three"
            ></mu-text-field>
          </mu-form-item>
          <mu-form-item class="main-login-input-check-form-item" prop="four">
            <mu-text-field
              id="input_four"
              v-model="codeCheckForm.four"
            ></mu-text-field>
          </mu-form-item>
        </mu-form>
        <div
          class="main-login-check-tip"
          v-if="verifyInterval"
          style="margin-bottom:162px;"
        >
          <span class="main-login-check-tip-second" style="margin-right:3px;"
            >{{ verifyTime }}s</span
          >后可重新获取验证码
        </div>
        <div
          class="main-login-check-tip-reset"
          v-else
          style="margin-bottom:162px;"
          @click="getVerifyCode(codeForm.phone)"
        >
          重新获取验证码
        </div>
        <div class="main-login-bottom">
          登录即代表同意学习王者的《<span class="main-login-bottom-name"
            >用户协议</span
          >》和《<span class="main-login-bottom-name">隐私政策</span>》
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      codeForm: {
        phone: "",
      },
      codeCheckForm: {
        one: "",
        two: "",
        three: "",
        four: "",
      },
      loginType: "wx",
      verifyInterval: null,
      verifyTime: "",
      baseImgUrl: "https://image.xuexiwangzhe.com/",
      qrCode: "",
      sign: "",
      from: "",
      wxWebsock: null,
      loginTimeInterval: null,
      loginTimeNumber: "",
      wxCodeLoading: false,
      bindWxCodeError: "",
      bindWxCodeSuccess: false,
      sessionKey: "",
    };
  },
  watch: {
    "codeCheckForm.one": function(newVal, oldVal) {
      if (newVal) {
        document.getElementById("input_two").focus();
        this.checkCode();
      }
    },
    "codeCheckForm.two": function(newVal, oldVal) {
      if (newVal) {
        document.getElementById("input_three").focus();
        this.checkCode();
      }
    },
    "codeCheckForm.three": function(newVal, oldVal) {
      if (newVal) {
        document.getElementById("input_four").focus();
        this.checkCode();
      }
    },
    "codeCheckForm.four": function(newVal, oldVal) {
      if (newVal) {
        this.checkCode();
      }
    },
    loginType: {
      handler: function(newVal, oldVal) {
        if (newVal == "bindwx") {
          this.bindWxCodeSuccess = false;
          this.bindWxCodeError = "";
          this.getWxCode("2");
        } else if (newVal == "wx") {
          this.getWxCode("1");
        } else if (newVal == "codecheck") {
          this.$nextTick(() => {
            document.getElementById("input_one").focus();
          });
        }
      },
      immediate: true,
    },
  },
  computed: {
    wxSocketUrl() {
      return `wss://minitool.xuexiwangzhe.com/miniapp/websocket/pcLogin/${this.sign}/${this.from}`;
    },
  },
  methods: {
    getVerifyCode(phone) {
      const params = { phone };
      this.$axios.get("/verifyCode/verifyCode", { params }).then((res) => {
        this.getVerifyCodeResHandle(res.success, res.msg);
      });
    },
    getWxCode(from) {
      this.wxCodeLoading = true;
      const params = {
        from,
      };
      this.$axios.get("/pcLogin/qrConnect", { params }).then((res) => {
        if (res.success) {
          this.qrCode = res.qrConnect;
          this.sign = res.sign;
          this.from = from;
          this.initWxWebSock();
        } else {
          this.$toast.error(res.msg);
        }
        this.wxCodeLoading = false;
      });
    },
    initWxWebSock() {
      if (this.from == "1") {
        this.wxWebsockLogin();
        return;
      }
      if (this.from == "2") {
        this.wxWebsockBind();
        return;
      }
    },
    wxWebsockLogin() {
      this.getWebSocket(this.wxSocketUrl, (e) => {
        if (e.data) {
          const result = JSON.parse(e.data);
          if (result.success && result.sessionKey) {
            this.loginSet(result.sessionKey);
          }
        }
      });
    },
    wxWebsockBind() {
      this.getWebSocket(this.wxSocketUrl, (e) => {
        if (e.data) {
          const result = JSON.parse(e.data);
          if (result.success && result.sessionKey && result.toIndex == 1) {
            this.bindWxCodeSuccess = true;
            this.sessionKey = result.sessionKey;
            this.loginTimeNumber = 3;
            this.loginTimeInterval = setInterval(() => {
              if (this.loginTimeNumber === 1) {
                clearInterval(this.loginTimeInterval);
                this.loginSet(result.sessionKey);
              } else {
                this.loginTimeNumber -= 1;
              }
            }, 1000);
          } else if (result.success && result.sessionKey) {
            this.wxWebsock.send(
              JSON.stringify({
                phone: this.codeForm.phone,
                verifyCode: parseInt(
                  this.codeCheckForm.one +
                    this.codeCheckForm.two +
                    this.codeCheckForm.three +
                    this.codeCheckForm.four
                ),
                password: "123456",
                userId: result.userId,
              })
            );
          } else if (!result.success) {
            this.$toast.error(result.msg);
            this.bindWxCodeError = result.msg;
          }
        }
      });
    },
    checkCode() {
      if (
        this.codeCheckForm.one &&
        this.codeCheckForm.two &&
        this.codeCheckForm.three &&
        this.codeCheckForm.four
      ) {
        const params = {
          phone: this.codeForm.phone,
          verifyCode: parseInt(
            this.codeCheckForm.one +
              this.codeCheckForm.two +
              this.codeCheckForm.three +
              this.codeCheckForm.four
          ),
          type: "phoneVerifyCode",
        };
        this.$axios.post("/pcLogin/pcLogin", params).then((res) => {
          if (res.success) {
            if (!res.identity) {
              this.$toast.success("登录成功");
              this.loginSet(res.sessionKey);
            } else {
              this.loginType = "bindwx";
            }
          } else {
            this.$toast.error(res.msg);
          }
        });
      }
    },
    loginSet(sessionKey) {
      sessionStorage.setItem("SESSIONKEY", sessionKey);
      this.$axios.interceptors.request.use(
        (config) => {
          var SESSIONKEY = sessionStorage.getItem("SESSIONKEY");
          if (SESSIONKEY) {
            config.headers.SESSIONKEY = SESSIONKEY;
          }
          return config;
        },
        (error) => {
          return Promise.reject(error);
        }
      );
      const dateNow = new Date().getTime();
      localStorage.setItem("loginTime", dateNow);
      location.href = "index.html";
    },
    getVerifyCodeResHandle(result, msg) {
      if (result) {
        this.codeCheckForm.one = "";
        this.codeCheckForm.two = "";
        this.codeCheckForm.three = "";
        this.codeCheckForm.four = "";
        this.loginType = "codecheck";
        this.verifyTime = 60;
        this.verifyInterval = setInterval(() => {
          if (this.verifyTime === 0) {
            clearInterval(this.verifyInterval);
            this.verifyInterval = null;
          } else this.verifyTime -= 1;
        }, 1000);
      } else {
        this.$toast.error(msg);
      }
    },
    getWebSocket(url, message) {
      this.wxWebsock = new WebSocket(url);
      this.wxWebsock.onerror = (event) => {
        console.log("websocket服务出错了");
        this.reconnect(url, message);
      };
      this.wxWebsock.onclose = (event) => {
        console.log("websocket服务关闭了");
        this.reconnect(url, message);
      };
      this.wxWebsock.onopen = (event) => {
        console.log("websocket服务打开了");
        this.reset();
        this.start();
      };
      this.wxWebsock.onmessage = (event) => {
        //如果获取到消息，心跳检测重置
        //拿到任何消息都说明当前连接是正常的
        console.log("websocket服务获得数据了");
        //接受消息后的UI变化
        if (event.data) {
          const result = JSON.parse(event.data);
          if (result.heartCheck) {
            console.log("收到心跳，重置");
            this.reset();
            this.start();
          }
        }
        message(event);
      };
    },
    reconnect(url, message) {
      if (this.lockReconnect) return;
      this.lockReconnect = true;
      //没连接上会一直重连，设置延迟避免请求过多
      setTimeout(() => {
        this.getWebSocket(url, message);
        this.lockReconnect = false;
      }, 2000);
    },
    reset() {
      clearTimeout(this.heartCheck.timeoutObj);
      clearTimeout(this.heartCheck.serverTimeoutObj);
    },
    start() {
      this.heartCheck.timeoutObj = setTimeout(() => {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        //onmessage拿到返回的心跳就说明连接正常
        this.wxWebsock.send(JSON.stringify({ heartCheck: 1 }));
        this.heartCheck.serverTimeoutObj = setTimeout(() => {
          //如果超过一定时间还没重置，说明后端主动断开了
          this.wxWebsock.close(); //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        }, this.heartCheck.timeout);
      }, this.heartCheck.timeout);
    },
  },
  destroyed() {},
};
</script>


<style lang="less">
html,
body {
  width: 100%;
  height: 100%;
}

body {
  background-color: #fff !important;
}

.page-login {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;

  .header {
    position: absolute;
    top: 24px;
    left: 30px;
    display: flex;
    font-size: 21px;
    align-items: center;
    color: #333;
    font-weight: bold;
  }

  .header-img {
    display: block;
    width: 24px;
    margin-right: 6px;
  }

  .wxcode-loading {
    display: block;
    margin: 30px auto;
  }

  .bindwx-title {
    color: #333;
    font-size: 27px;
    text-align: center;
    font-weight: bold;
    margin-bottom: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .bindwx-title-img {
    width: 30px;
    display: block;
    margin-right: 15px;
  }

  .bindwx-tip {
    color: #999;
    font-size: 15px;
    font-weight: bold;
    text-align: center;
  }

  .bindwx-img {
    display: block;
    width: 240px;
    margin: 0 auto 21px auto;
  }

  .main {
    display: flex;
    align-items: center;
  }

  .main-info {
    margin-right: 93px;
  }

  .main-info-tip {
    color: #333;
    font-size: 24px;
    margin-bottom: 18px;
    text-align: left;
    padding-left: 27px;
  }

  .main-info-img {
    width: 453px;
  }

  .main-login-box {
    position: relative;
    width: 390px;
    text-align: center;
    background: #ffffff;
    box-shadow: 0px 2px 9px 0px rgba(102, 102, 102, 0.2);
    border-radius: 12px;
  }

  .main-login-select {
    position: absolute;
    right: 12px;
    top: 12px;
    cursor: pointer;
  }

  .main-login-select-img {
    width: 81px;
  }

  .main-login-back {
    position: absolute;
    left: 18px;
    top: 18px;
    cursor: pointer;
  }

  .main-login-back-img {
    width: 18px;
  }

  .main-login-title {
    font-size: 30px;
    color: #333;
    font-weight: bold;
    padding-top: 75px;
    margin-bottom: 103px;
  }

  .main-login-check-tip {
    font-size: 12px;
    color: #999999;

    &-phone,
    &-second {
      color: #333;
    }
  }

  .main-login-check-tip-reset {
    cursor: pointer;
    color: #265bff;
    font-size: 12px;
  }

  .main-login-check-form {
    margin-bottom: 41px;
    justify-content: center;
  }

  .main-login-input-check-form-item {
    &:last-child {
      margin-right: 0;
    }
    .mu-text-field-input {
      text-align: center;
    }
    width: 54px;
    min-width: 0 !important;
    margin-right: 23px;
  }

  .main-login-qr-img {
    width: 150px;
    margin-bottom: 9px;
  }

  .main-login-qr-tip {
    font-size: 15px;
    color: #333;
    font-weight: bold;
    margin-bottom: 6px;
  }

  .main-login-input-form-item {
    margin: 0 auto 41px auto;
    padding-bottom: 0;
    width: 285px;
  }

  .main-login-btn-form-item {
    width: 285px;
    margin: 0 auto 23px auto;
    padding-bottom: 0;
    min-height: 0;

    .main-login-btn {
      width: 100%;
      height: 35px;
      background: #265cff;
      border-radius: 17px;
      margin: 0;
      color: #fff;
      box-shadow: none;

      &-disabled {
        background-color: #e6e6e6;
      }
    }
  }

  .main-login-tip {
    color: #666;
    font-size: 11px;
    margin-bottom: 106px;
  }

  .main-login-bottom {
    color: #666;
    font-size: 11px;
    padding-bottom: 24px;
  }

  .main-login-bottom-name {
    color: #265bff;
  }
}
</style>
